#ifndef udp_client_HPP_
#define udp_client_HPP_

#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <queue>

namespace gimabl {

#define READ_BUFFER_SIZE 1024
#define Mutil_Wait_Time 1000   // ms
#define MAX_QUEUE_SIZE 10   

enum ThreadMode{
    single= 0,
    mutiple= 1
};

class UdpClient{

    typedef std::function<int32_t(uint8_t*,std::size_t)> udpRecHandle;

public:
    UdpClient(ThreadMode mode=single);
    ~UdpClient();

    int32_t udpInit(std::string serverIp,int32_t serverPort,int32_t port=1114);
    int32_t udpWrite(const void *buf,size_t size);
    void udpRead(udpRecHandle handle,int32_t timeoutMs);

    void udpClose();
    bool isStop();
    
private:
    int32_t udpSend(const void *buf,size_t size);
    void receiveMssages(); //接收消息
    void mutilSendMessages(); //多线程发送消息

    ThreadMode m_mode;
    int32_t m_sockfd;
    int32_t m_port;
    bool m_isConnect;
    bool m_stop;
    
    sockaddr_in m_serverAddr;
    socklen_t m_serverLen;

    std::thread m_receiverThread;
    udpRecHandle m_receiveHandle;
    int32_t m_timeoutMs;  // 超时时间

    std::thread m_sendThread;
    std::queue<std::string> m_sendQueue;  // 发送缓冲区
    std::mutex m_sendMutex;  // 发送缓冲区的互斥锁
    std::condition_variable send_cv;  // 用于发送缓冲区的条件变量
};

}
#endif

